package com.syh.jn.scm.service.impl.operation.system;

import cn.redscarf.commons.util.bean.ExtBeanUtils;
import cn.redscarf.commons.util.other.ExtAssert;
import cn.redscarf.commons.util.other.ExtStringUtils;
import cn.redscarf.commons.wrapper.Restrictions;
import cn.redscarf.commons.wrapper.Wrapper;
import com.alibaba.dubbo.config.annotation.Service;
import com.syh.core.ddd.infrastructure.repository.AggregateRepository;
import com.syh.core.ddd.service.AbstractServiceImpl;
import com.syh.jn.scm.domain.operation.entity.system.OperationMenu;
import com.syh.jn.scm.domain.operation.repository.system.OperationMenuReadRepository;
import com.syh.jn.scm.domain.operation.repository.system.OperationMenuRepository;
import com.syh.jn.scm.domain.operation.repository.system.PermissionRepository;
import com.syh.jn.scm.dto.operation.system.menu.OperaMenuMto;
import com.syh.jn.scm.dto.operation.system.menu.OperaMenuSto;
import com.syh.jn.scm.dto.operation.system.menu.OperaMenuVo;
import com.syh.jn.scm.dto.operation.system.permission.PermissionMto;
import com.syh.jn.scm.dto.operation.system.permission.PermissionVo;
import com.syh.jn.scm.infrastructure.repository.model.system.MenuPermissionModel;
import com.syh.jn.scm.service.api.operation.system.OperationMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
@Transactional
public class OperationMenuServiceImpl implements OperationMenuService {

  @Autowired
  private OperationMenuRepository operationMenuRepository;
  @Autowired
  private OperationMenuReadRepository operationMenuReadRepositoryMbImpl;

  @Autowired
  private PermissionRepository permsRepository;


  @Override
  public Long save(OperaMenuSto menuSto) {
    ExtAssert.notNull(menuSto, "对象为空");
    OperationMenu operationMenu = OperationMenu.create(menuSto);
    return operationMenuRepository.add(operationMenu);
  }

  @Override
  public void update(OperaMenuMto menuMto) {
    ExtAssert.notNull(menuMto, "对象为空");
    OperationMenu operationMenu = operationMenuRepository.getById(menuMto.getId());
    operationMenu.modify(menuMto);
    operationMenuRepository.update(operationMenu);
  }

  @Override
  public void enabled(Long id) {
    ExtAssert.notNull(id, "id为空");
    OperationMenu operationMenu = operationMenuRepository.getById(id);
    operationMenu.enabled();
    this.recursionEnabled(operationMenu);
  }

  private void recursionEnabled(OperationMenu parent) {
    if (parent.getParent() != null) {
      this.recursionEnabled(parent.getParent());
    }
    this.operationMenuRepository.update(parent);
  }

  @Override
  public void disabled(Long id) {
    ExtAssert.notNull(id, "id为空");
    OperationMenu operationMenu = operationMenuRepository.getById(id);
    operationMenu.disabled();
    disabledMenu(operationMenu);
  }

  private void disabledMenu(OperationMenu operationMenu) {
    if (operationMenu.getSubOperationMenus() != null) {
      operationMenu.getSubOperationMenus().forEach(subMenu -> {
        disabledMenu(subMenu);
      });
    }
    operationMenuRepository.update(operationMenu);
  }


  @Override
  public void delete(Long id) {
    ExtAssert.notNull(id, "id为空");
    OperationMenu operationMenu = operationMenuRepository.getById(id);
    operationMenu.destroy();
    operationMenuRepository.removeById(id);
  }

  @Override
  public void mountPermission(Long id, List<PermissionMto> permsMtoList) {
    ExtAssert.notNull(id, "id为空");
    Set<Long> hadPermsId = new HashSet<>();
    Set<Long> permsId = new HashSet<>();
    List<MenuPermissionModel> MenuPermsSaveList = new ArrayList<>();
    List<Long> menuPermsDeleteIds = new ArrayList<>();
    //记录当前菜单已拥有的权限
    List<PermissionVo> permsVoList = permsRepository.getPermissionByMenuId(id);
    permsVoList.forEach(permsVo -> {
      hadPermsId.add(permsVo.getId());
    });
    //记录当前菜单本次提交的权限修改
    permsMtoList.forEach(permsMto -> {
      permsId.add(permsMto.getId());
    });
    //找出需要新增的权限
    permsMtoList.forEach(permsMto -> {
      if (!hadPermsId.contains(permsMto.getId())) {
        MenuPermissionModel menus = new MenuPermissionModel();
        menus.setMenuId(id);
        menus.setPermissionId(permsMto.getId());
        MenuPermsSaveList.add(menus);
      }
    });
    //找出需要删除的权限
    permsVoList.forEach(permsVo -> {
      if (!permsId.contains(permsVo.getId())) {
        menuPermsDeleteIds.add(permsVo.getId());
      }
    });
    //持久化
    MenuPermsSaveList.forEach(munePerm -> {
      operationMenuRepository.updateMenuPermission(munePerm);
    });
    if (!menuPermsDeleteIds.isEmpty())
      operationMenuRepository.removeMenuPermissionByIds(id, menuPermsDeleteIds);
  }

  @Override
  public OperaMenuVo getById(Long aLong) {
    return operationMenuReadRepositoryMbImpl.getById(aLong);
  }

  @Override
  public OperaMenuVo getOne(Wrapper wrapper) {
    return operationMenuReadRepositoryMbImpl.getOne(wrapper);
  }

  @Override
  public boolean contains(Long aLong) {
    return operationMenuReadRepositoryMbImpl.contains(aLong);
  }

  @Override
  public List<OperaMenuVo> findList(Wrapper wrapper) {
    return operationMenuReadRepositoryMbImpl.getList(wrapper);
  }

  @Override
  public List<OperaMenuVo> findListPage(Wrapper wrapper, Integer startRow, Integer count) {
    return operationMenuReadRepositoryMbImpl.findListPage(wrapper, startRow, count);
  }

  @Override
  public int getCount(Wrapper wrapper) {
    return operationMenuReadRepositoryMbImpl.getCount(wrapper);
  }

  @Override
  public void fixOldDataCode() {
    operationMenuRepository.fixOldDataCode();
  }
}
